package MtG.publicClass;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;

/**
 * Player.java holds all the info about the player.
 * @author Marek Sirp
 * @author Jaan Sepp
 */
public class Player implements Serializable{
	/**
	 * Determines if a de-serialized file is compatible with this class.
	 */
	private static final long serialVersionUID = 7218585181897014204L;
	
	/**
	 * Constructor.
	 */
	public Player(){
		Date now = new Date();
		long msec = now.getTime();
		securityNumber = Long.toString(msec);
	}
	
	
	private UUID lastClickedCard;	
	/**
	 * Field that holds the clients (players) name.
	 */
	private String clientName = "";
	/**
	 * Boolean that keep track of whether the player has played a mana card this turn.
	 */
	private boolean manaPlaced = false;
	/**
	 * Constant for maximum cards in hand
	 */
	private final int MAXCARDINHAND = 7;
	/**
	 * Field that references to the deck of this player.
	 */
	private Deck deck = null;
	/**
	 * Field that references the unique securityNumber of each player.
	 */
	private String securityNumber;
	/**
	 * Maximum mana that the player can currently have.
	 */
	private int maxMana = 0;
	/**
	 * Current mana that the player has, cannot be bigger value than maxMana variable.
	 */
	private int initMana = 0;
	/**
	 * Boolean that defines if the player is just a specatator or a real player.
	 */
	private boolean spectator = true;
	/**
	 * Initial hit points that the player has.
	 */
	private int playerHitPoints = 20;
	/**
	 * ArrayList that keeps record of what cards this player has in his hand.
	 */
	private ArrayList<Card> cardsInHand = new ArrayList<Card>();
	/**
	 * ArrayList that keeps record of what cards this player has on the game table.
	 */
	private ArrayList<Card> cardsInPlay = new ArrayList<Card>();	
	/**
	 * @return retrieve the manaPlaced boolean value 
	 * (TRUE if a mana card has already been played this turn
	 *  and FALSE if it has not.)
	 */
	public boolean isManaPlaced() {
		return manaPlaced;
	}

	/**
	 * @param manaPlaced the value to be set to the boolean
	 * "manaPlaced".
	 */
	public void setManaPlaced(boolean manaPlaced) {
		this.manaPlaced = manaPlaced;
	}

	
	/**
	 * @param name name to be given to the client and used as part of the security number.
	 */
	public void setClientName(String name){
		this.clientName = name;
		securityNumber += name;
		System.out.println(securityNumber);
	}
		
	/**
	 * @return this clients name.
	 */
	public String getName(){
		return this.clientName;
	}
	
	/**
	 * @return retrieve the maximum mana the player can have as an integer.
	 */
	public int getMaxMana() {
		return maxMana;
	}

	/**
	 * @param maxMana integer that will be added to the maximum mana this player can have.
	 */
	public void setMaxMana(int maxMana) {
		this.maxMana += maxMana;
		this.initMana += maxMana;
	}

	/**
	 * @return retrieve mana left for this player as an integer.
	 */
	public int getInitMana() {
		return initMana;
	}

	/**
	 * @param initMana the number that will be set as the mana left for this player.
	 */
	public void setInitMana(int initMana) {
		this.initMana = initMana;
	}	
	/**
	 * @param spec boolean value that represents if this player will be a spectator.
	 */
	public void setSpectator(boolean spec){
		this.spectator = spec;
	}
	
	/**
	 * @return retrieve whether or not this player is spectator or an actual player.
	 */
	public boolean isSpectator(){
		return spectator;
	}
	
	/**
	 * @param amount number of cards that will be drawn from the deck.
	 */
	public void drawCardFromDeck(int amount){
		if(cardsInHand.size()<MAXCARDINHAND){
					for(int i = 0 ; i<amount; i++){
			addCardToHand(deck.takeRandomCard());
		}
		}

	}
	
	
	/**
	 * @param currentDeck sets this deck as the players usable deck.
	 */
	public void setDeck(Deck currentDeck){
		this.deck = currentDeck;
	}
	
	/**
	 * @return retrieves the deck that this player uses.
	 */
	public Deck getDeck() {
		return deck;
	}
	
	/**
	 * @param currentCard adds a card to the players hand.
	 */
	public void addCardToHand(Card currentCard){
		this.cardsInHand.add(currentCard);
	}
	
	/**
	 * @return ArrayList of cards in the players hand.
	 */
	public ArrayList<Card> getPlayersHand(){
		return this.cardsInHand;
	}
	
	/**
	 * @param currentCard card to be removed from the players hand.
	 */
	public void removeCardFromHand(Card currentCard){
		this.cardsInHand.remove(currentCard);
	}
	
	/**
	 * @param currentCard card that will be added in play by the player.
	 */
	public void addCardToPlay(Card currentCard){
		this.cardsInPlay.add(currentCard);
	}
	
	public UUID getLastClickedCard() {
		return lastClickedCard;
	}

	public void setLastClickedCard(UUID lastClickedCard) {
		this.lastClickedCard = lastClickedCard;
	}

	/**
	 * @return ArrayList of cards this player has on the table.
	 */
	public ArrayList<Card> getPlayersCardsInPlay(){
		return this.cardsInPlay;
	}
	
	/**
	 * @param currentCard card to be removed from play from this player.
	 */
	public void removeCardFromPlay(Card currentCard){
		this.cardsInPlay.remove(currentCard);
	}
	
	/**
	 * @param damage integer number that shows how much the players HP needs to be decreased. 
	 */
	public void decreaseHitPoints(int damage){
		this.playerHitPoints = playerHitPoints - damage;
		if(this.playerHitPoints<0){
			this.playerHitPoints = 0;
		}
		
	}
	
	/**
	 * @return this players current hit points.
	 */
	public int getCurrentHitPoints(){
		return this.playerHitPoints;
	}
	
	/**
	 * @return retrieve the unique combination of time and players name.
	 */
	public String getSecurityNumber(){
		return securityNumber;
	}
	
	/**
	 * reset function for player
	 */
	public void playerReset(){
		manaPlaced = false;
		maxMana = 0;
		initMana = 0;
		spectator = true;
		playerHitPoints = 20;
		cardsInHand = new ArrayList<Card>();
		cardsInPlay = new ArrayList<Card>();	
	}
}
